const WowClient = function () {
    this.cache = {
        version: 0,
        levelExpMap: []
    };
    this.cacheKey = "idlewow_client_cache";
    this.hubUrl = "ws://localhost:20010/hub";
    this.webSocket = new WebSocket(this.hubUrl);
    this.webSocket.onopen = function (event) {
        console.log('WebSocket建立连接');
        wowClient.sendLogin();
        wowClient.loadCache();
    };
    this.webSocket.onmessage = function (event) {
        console.log('WebSocket收到消息：%c' + event.data, 'color:green');
        var message = JSON.parse(event.data) || {};
        console.log(message);
        wowClient.receive(message);
    };
    this.webSocket.onclose = function (event) {
        console.log('WebSocket关闭连接');
    };
    this.webSocket.onerror = function (event) {
        console.log('WebSocket发生异常');
    };
};

const RequestMessage = function () {
    this.header = {
        messageCode: "",
        requestTime: new Date(),
        version: "1.0"
    };
    this.content = {};
};

const MessageCode = {
    // 预处理
    LoadCache: "0010",
    // 系统命令
    Login: "1001",
    RefreshOnline: "1002",
    // 玩家命令
    Chat: "2001",
    Move: "2002",
    BattleMob: "2100"
};

WowClient.prototype = {
    //////////////////
    //// 对外接口 ////
    //////////////////
    // 读取缓存
    loadCache: function () {
        let storage = localStorage.getItem(this.cacheKey);
        let cache = storage ? JSON.parse(storage) : null;
        if (!cache || (new Date().getTime() - cache.version) > 1000 * 60 * 60 * 24) {
            this.sendLoadCache();
        } else {
            this.cache = cache;
        }
    },
    //////////////////
    //// 消息处理 ////
    //////////////////
    // 接收消息
    receive: function (message) {
        console.log('receive');
        console.log(message);
        switch (message.header.messageCode) {
            case MessageCode.LoadCache:
                this.recvLoadCache(message);
                break;
            case MessageCode.RefreshOnline:
                this.recvRefreshOnline(message);
                break;
            case MessageCode.Login:
                this.recvLogin(message);
                break;
            case MessageCode.Chat:
                this.recvChat(message);
                break;
            case MessageCode.Move:
                this.recvMove(message);
                break;
            case MessageCode.BattleMob:
                this.recvBattleMob(message);
                break;
            default:
                break;
        }
    },
    // 读取缓存
    sendLoadCache: function () {
        let requestMessage = new RequestMessage();
        requestMessage.loadCache();
        let msg = JSON.stringify(requestMessage);
        this.webSocket.send(msg);
    },
    recvLoadCache: function (message) {
        this.cache.levelExpMap = message.content.levelExpMap;
        this.cache.version = new Date().getTime();
        localStorage.setItem(this.cacheKey, JSON.stringify(this.cache));
    },
    // 刷新在线列表
    sendRefreshOnline: function () {
        let requestMessage = new RequestMessage();
        requestMessage.refreshOnline();
        let msg = JSON.stringify(requestMessage);
        this.webSocket.send(msg);
    },
    recvRefreshOnline: function (message) {
        this.refreshOnlineInfo(message.content.onlineInfo);
    },
    // 登陆
    sendLogin: function () {
        let requestMessage = new RequestMessage();
        requestMessage.login();
        let msg = JSON.stringify(requestMessage);
        this.webSocket.send(msg);
    },
    recvLogin: function (message) {
        this.refreshMapInfo(message.content.mapInfo);
        this.refreshOnlineInfo(message.content.onlineInfo);
    },
    // 聊天
    sendChat: function () {
        let requestMessage = new RequestMessage();
        requestMessage.chat();
        let msg = JSON.stringify(requestMessage);
        this.webSocket.send(msg);
    },
    recvChat: function (message) {
        let channel = "【当前】";
        let content = "<p>" + channel + message.content.senderName + ": " + message.content.message + "</p>";
        $('.msg-chat').append(content);
    },
    // 移动
    sendMove: function (mapId) {
        let requestMessage = new RequestMessage();
        requestMessage.move(mapId);
        let msg = JSON.stringify(requestMessage);
        this.webSocket.send(msg);
    },
    recvMove: function (message) {
        console.log("recvMove");
        console.log(message);
        this.refreshMapInfo(message.content.mapInfo);
        this.refreshOnlineInfo(message.content.onlineInfo);
    },
    // 战斗
    sendBattleMob: function (mobId) {
        let requestMessage = new RequestMessage();
        requestMessage.battleMob(mobId);
        let msg = JSON.stringify(requestMessage);
        this.webSocket.send(msg);
    },
    recvBattleMob: async function (message) {
        $('.msg-battle').html('');
        let battleResult = message.content.battleResult;
        if (battleResult.roundList) {
            var rounds = battleResult.roundList;
            for (var i = 0; i < rounds.length; i++) {
                var round = rounds[i];
                var content = "<p>【第" + round.round + "回合】</p>";
                if (round.atkStage) {
                    content += "<p>" + round.atkStage.desc + "</p>";
                }

                if (round.defStage) {
                    content += "<p>" + round.defStage.desc + "</p>";
                }

                $('.msg-battle').append(content);
                await this.sleep(1500);
            }

            $('.msg-battle').append("<p><strong>战斗结束，" + battleResult.winName + " 获得胜利！</strong></p>");
            if (battleResult.isPlayerWin) {
                this.settlement(battleResult);
            }

            let that = this;
            await this.sleep(5000).then(function () {
                that.sendBattleMob(battleResult.atkId, battleResult.defId);
            });
        }
    },
    //////////////////
    //// 辅助方法 ////
    //////////////////
    // 刷新地图信息
    refreshMapInfo: function (mapInfo) {
        let wowMap = mapInfo.wowMap;
        let mapCoordList = mapInfo.mapCoordList;
        $('#mapName').html(wowMap.name);
        $('#mapDesc').html(wowMap.description);
        $('#mapImg').attr('src', '/images/wow/map/' + wowMap.name + '.jpg');
        let coordsHtml = '';
        for (let index in mapCoordList) {
            let mapCoord = mapCoordList[index];
            coordsHtml += '<area shape="' + mapCoord.shape + '" coords="' + mapCoord.coord + '" onclick="wowClient.sendMove(\'' + mapCoord.destMapId + '\');" href="javascript:void(0);" alt="' + mapCoord.destMapName + '" title="' + mapCoord.destMapName + '"/>';
        }

        $('#map-coords').html(coordsHtml);
    },
    // 刷新在线列表
    refreshOnlineInfo: function (onlineInfo) {
        let mapCharacterList = onlineInfo.mapCharacterList;
        let mapMobList = onlineInfo.mapMobList;
        // 更新在线列表
        $('#online-all').html('');
        $('#online-player').html('');
        $('#online-mob').html('');
        for (let index in mapCharacterList) {
            let mapCharacter = mapCharacterList[index];
            let row = '<div class="layui-row"><div class="layui-col-md9"><label style="color: blue;">' + mapCharacter.name + '</label><label> - 等级：' + mapCharacter.level + '</label></div><div class="layui-col-md3"><button type="button" style="height:14px;line-height: 14px;">私聊</button></div></div>';
            $('#online-all').append(row);
            $('#online-player').append(row);
        }

        for (let index in mapMobList) {
            let mapMob = mapMobList[index];
            let row = '<div class="layui-row"><div class="layui-col-md9"><label style="color: red;">' + mapMob.name + '</label><label> - 等级：' + mapMob.level + '</label></div><div class="layui-col-md3"><button type="button" style="height:14px;line-height: 14px;" onclick="wowClient.sendBattleMob(\'' + mapMob.id + '\');">战斗</button><button type="button" style="height:14px;line-height:14px;" onclick="guaji();">挂机</button></div></div>';
            $('#online-all').append(row);
            $('#online-mob').append(row);
        }
    },
    // 战斗结算
    settlement: function (battleResult) {
        $('.lbl-level').html(battleResult.settleLevel);
        $('.lbl-exp').html(battleResult.settleExp);
    },
    // 休眠
    sleep: function (milliseconds) {
        let p = new Promise(function (resolve) {
            setTimeout(function () {
                resolve();
            }, milliseconds)
        });
        return p;
    },
    // 关闭
    close: function () {
        this.webSocket.close();
    }
};

RequestMessage.prototype = {
    loadCache: function () {
        this.header.messageCode = MessageCode.LoadCache;
    },
    login: function () {
        this.header.messageCode = MessageCode.Login;
    },
    chat: function () {
        this.header.messageCode = MessageCode.Chat;
        this.content = {
            senderId: charId,
            senderName: charName,
            receiverId: '',
            receiverName: '',
            message: $('#msg').val()
        };
    },
    move: function (mapId) {
        this.header.messageCode = MessageCode.Move;
        this.content = {
            destMapId: mapId
        };
    },
    battleMob: function (mobId) {
        this.header.messageCode = MessageCode.BattleMob;
        this.content = {
            mobId: mobId
        };
    },
    refreshOnline: function () {
        this.header.messageCode = MessageCode.RefreshOnline;
    }
};

// wow客户端
window.wowClient = new WowClient();

// 关闭窗口
window.onbeforeunload = function (event) {
    wowClient.close();
};

document.onkeydown = function (event) {
    let e = event || window.event || arguments.callee.caller.arguments[0];
    if (e.keyCode === 13 && document.activeElement.id === 'msg') {
        wowClient.sendChat();
    }
};
